<?php

namespace app\http\controller\admin;

use FApi\App;
use Laf\Rbac;
use Laf\Session;
use app\libs\View;
use mon\env\Config;
use app\model\MenuModel;
use Laf\Controller as LafController;

/**
 * Admin模块控制器基类
 */
abstract class Controller extends LafController
{
    /**
     * 用户信息
     *
     * @var array
     */
    protected $userInfo = [];

    /**
     * 插件扩展的RequireJS资源配置
     *
     * @var array
     */
    protected $assetsConfig = [];

    /**
     * 权限管理驱动
     *
     * @var \mon\auth\rbac\Auth
     */
    protected $auth;

    /**
     * 视图驱动
     *
     * @var View
     */
    protected $view;

    /**
     * 管理端视图路径
     *
     * @var string
     */
    protected $viewPath = APP_PATH . '/view/admin/';

    /**
     * 构造方法
     */
    public function __construct()
    {
        parent::__construct();
        // 加载权限驱动
        $this->auth = Rbac::instance()->getService();
        // 加载视图驱动
        $this->view = new View($this->viewPath);
        // 获取Session中的用户信息
        $this->userInfo = Session::instance()->get(Config::instance()->get('admin.admin_session_key'));
        // 初始化重定向
        $this->initRefer();
        // 初始化面包屑
        $this->initCrumb();
        // 配置信息
        $this->initConfig();
    }

    /**
     * 初始化重定向配置
     *
     * @return void
     */
    protected function initRefer()
    {
        // 非选项卡时重定向
        if (
            !$this->request->isPost() &&
            !$this->request->isAjax() &&
            !$this->request->params('addtabs') &&
            !$this->request->params('dialog') &&
            $this->request->params('ref') == 'addtabs'
        ) {
            $url = preg_replace_callback("/([\?|&]+)ref=addtabs(&?)/i", function ($matches) {
                return $matches[2] == '&' ? $matches[1] : '';
            }, $this->request->uri());

            $redirect = $this->url->build('/admin/index', ['refer' => $url]);
            $this->url->redirect($redirect);
            exit;
        }
    }

    /**
     * 初始化面包屑相关
     *
     * @return void
     */
    protected function initCrumb($uri = '')
    {
        $uri = empty($uri) ? $this->request->pathInfo() : $uri;
        $breadcrumb = $this->getBreadCrumb($uri);
        $this->assign('breadcrumb', $breadcrumb);
    }

    /**
     * 初始化相关配置
     *
     * @return void
     */
    protected function initConfig()
    {
        // 加载requirejs资源依赖配置
        $assetsConfig = $this->getAssetsConfig();
        // 定义执行的js回调
        list($controller, $action) = explode('@', App::instance()->getController());
        $ctrl = strtolower($controller);
        $jsname = str_replace('app\http\controller\\', 'js/', $ctrl);
        // 移除最后的controller字符串
        $jsname = str_replace('controller', '', $jsname);
        $jsname = str_replace('\\', '/', $jsname);
        // 定义配置信息
        $config = [
            'site'          => Config::instance()->get('admin.site'),
            'multiplenav'   => Config::instance()->get('admin.multiplenav'),
            'actionname'    => $action,
            'jsname'        => $jsname,
            'refer'         => $this->request->get('refer', ''),
        ];

        // 渲染配置信息
        $this->assign('config', $config);
        $this->assign('configJson', json_encode($config, JSON_UNESCAPED_UNICODE));
        $this->assign('assetsConfig', $assetsConfig);
        $this->assign('assetsConfigJson', json_encode($assetsConfig, JSON_UNESCAPED_UNICODE));

        // 渲染用户信息
        $this->assign('userInfo', $this->userInfo);
    }

    /**
     * 获取面包屑导航
     *
     * @param  string $uri [description]
     * @return array
     */
    protected function getBreadCrumb($uri = '')
    {
        static $breadCrumb = [];
        if ($breadCrumb || !$uri) {
            return $breadCrumb;
        }

        $menu_id = 0;
        $menus = MenuModel::instance()->where('status', 1)->select();
        foreach ($menus as $menu) {
            if ($menu['name'] == $uri) {
                $menu_id = $menu['id'];
                // 赋值获取当前菜单栏目信息
                $this->crumb = $menu;
                break;
            }
        }
        // 得到ID
        if ($menu_id) {
            $breadCrumb = $this->container->tree->data($menus)->getParents($menu_id, true);
        }

        return $breadCrumb;
    }

    /**
     * 获取资源
     *
     * @return array
     */
    protected function getAssetsConfig()
    {
        $assetsConfig = Config::instance()->get('admin.assets', []);
        if (empty($this->assetsConfig)) {
            return $assetsConfig;
        }
        // 存在自定义，进行资源重载合并
        foreach ($this->assetsConfig as $key => $item) {
            switch ($key) {
                case 'baseUrl':
                    $assetsConfig['baseUrl'] = $item;
                    break;
                case 'paths':
                case 'shim':
                case 'map':
                    foreach ($item as $name => $path) {
                        $assetsConfig[$key][$name] = $path;
                    }
                    break;
            }
        }

        return $assetsConfig;
    }

    /**
     * 模版赋值
     *
     * @param mixed $key    赋值数据
     * @param mixed $value  值
     * @return void
     */
    protected function assign($key, $value = null)
    {
        return $this->view->assign($key, $value);
    }

    /**
     * 输出视图
     *
     * @param string $path  视图名称
     * @param array $data   视图数据
     * @return string
     */
    protected function fetch($path = '', $data = [])
    {
        return $this->view->fetch($path, $data);
    }
}
